<script lang="ts" setup>
import { VueCropper } from 'vue-cropper'
import type { SpCropperFile, SpCropperOption } from '@/components/SpCropper/type'
import axios from 'axios'

type Props = SpCropperOption

const open = defineModel()
const props = withDefaults(defineProps<Props>(), {
  img: '',
  loading: false,
  /** 预览是否圆形 */
  previewRound: true,
  /* 容器宽度 */
  boxWidth: 500,
  /* 容器高度 */
  boxHeight: 380,
  /* 裁剪生成图片的质量 */
  outputSize: 1,
  /* 默认生成截图框宽度 */
  autoCropWidth: '200',
  /* 默认生成截图框高度 */
  autoCropHeight: '200',
  /* 裁剪生成图片的格式 */
  outputType: 'jpeg',
  /* 裁剪框的大小信息 */
  info: true,
  /* 图片是否允许滚轮缩放 */
  canScale: true,
  /* 是否默认生成截图框 */
  autoCrop: true,
  /* 是否开启截图框宽高固定比例 */
  fixed: false,
  /* 是否输出原图比例的截图 */
  full: false,
  /* 固定截图框大小 */
  fixedBox: true,
  /* 上传图片是否可以移动 */
  canMove: true,
  /* 截图框能否拖动 */
  canMoveBox: true,
  /* 上传图片按照原始比例渲染 */
  original: false,
  /* 截图框是否被限制在图片里面 */
  centerBox: false,
  /* 是否按照设备的dpr 输出等比例图片 */
  high: true,
  /* true 为展示真实输出图片宽高 false 展示看到的截图框宽高 */
  infoTrue: false,
  /* 限制图片最大宽度和高度 */
  maxImgSize: 2000,
  /* 图片根据截图框输出比例倍数 */
  enlarge: 1,
  /* 图片默认渲染方式 */
  mode: 'contain',
  /* 裁剪框限制最小区域 */
  limitMinSize: 10
})

const img = ref(props.img)

if (img.value.includes('http')) {
  axios.get(img.value, { responseType: 'blob' }).then((res) => {
    console.log(res)
  })
}

async function convertImageToBase64() {
  try {
    const response = await axios.get(img.value)
    const file = new Blob([response.data], { type: 'image/jpeg' })

    // 使用FileReader读取Blob数据
    const reader = new FileReader()
    reader.onloadend = () => {
      img.value = reader.result
    }
    reader.readAsDataURL(file)
  } catch (error) {
    console.error('Error fetching or converting the image:', error)
  }
}

// 裁剪框宽度
const width = ref(props.autoCropWidth)
// 裁剪框高度
const height = ref(props.autoCropHeight)
// 裁剪框样式
const newOptions = ref({ ...props })
// 预览样式
const previewStyle = ref()
// 预览样式
const previewShowStyle = ref()
// cropper Ref
const cropper = ref(VueCropper)
// 文件数据
const fileData = reactive<SpCropperFile>({
  fileName: newOptions.value.img
})

// 实时预览
const realTime = (data: any) => {
  previewShowStyle.value = {
    width: data.w + 'px',
    height: data.h + 'px',
    borderRadius: newOptions.value.previewRound ? '50%' : ''
  }
  previewStyle.value = data.img
}

// 放大
const amplify = () => {
  cropper.value.changeScale(2)
}
// 缩小
const reduction = () => {
  cropper.value.changeScale(-2)
}
//向左转
const leftTurn = () => {
  cropper.value.rotateRight()
}
//向右转
const rightTurn = () => {
  cropper.value.rotateLeft()
}
//提交
const cropperSubmit = () => {
  newOptions.value.loading = true
  cropper.value.getCropBlob((data) => {
    fileData.file = data
    newOptions.value.beforeSubmit(fileData).then((res) => {
      open.value = false
      newOptions.value.loading = false
    })
  })
}
const fileInput = ref()

const upload = () => {
  fileInput.value.click()
}

// 选择图片
const handleFileChange = (event) => {
  const files = event.target.files
  if (files && files.length > 0) {
    // 限制只能上传图片
    const file = files[0]
    if (!file.type.match('image.*')) {
      alert('请选择图片文件！')
      return
    }
    fileData.fileName = file.name
    // 例如，可以读取文件内容
    const reader = new FileReader()
    reader.onload = (e) => {
      const arrayBuffer = e.target.result
      let blob = new Blob([arrayBuffer], { type: file.type })
      newOptions.value.img = URL.createObjectURL(blob)
    }
    reader.readAsArrayBuffer(file)
  }
}
</script>
<template>
  <a-modal v-model:open="open" :footer="null" :width="newOptions.boxWidth + 500" title="裁剪图片">
    <div class="cropper">
      <div
        :style="{
          width: newOptions.boxWidth + 'px'
        }"
        class="left"
      >
        <div
          :style="{
            height: newOptions.boxHeight + 'px'
          }"
          class="cut"
        >
          <vue-cropper ref="cropper" v-bind="newOptions" @realTime="realTime"> </vue-cropper>
        </div>
        <!--  隐藏上传图片框  -->
        <input
          ref="fileInput"
          accept="image/*"
          style="display: none"
          type="file"
          @change="handleFileChange"
        />
        <div class="cropper-handle">
          <a-space :size="15">
            <a-tooltip>
              <template #title>上传图片</template>
              <a-button size="small" @click="upload">
                <template #icon>
                  <Icon type="icon-upload" />
                </template>
              </a-button>
            </a-tooltip>
            <a-tooltip>
              <template #title>放大</template>
              <a-button size="small" @click="amplify">
                <template #icon>
                  <Icon type="icon-plus" />
                </template>
              </a-button>
            </a-tooltip>
            <a-tooltip>
              <template #title>缩小</template>
              <a-button size="small" @click="reduction">
                <template #icon> <Icon type="icon-minus" /> </template>
              </a-button>
            </a-tooltip>
            <a-tooltip>
              <template #title>左转</template>
              <a-button size="small" @click="leftTurn">
                <template #icon> <Icon type="icon-rotate-left" /> </template>
              </a-button>
            </a-tooltip>
            <a-tooltip>
              <template #title>右转</template>
              <a-button size="small" @click="rightTurn">
                <template #icon> <Icon type="icon-rotate-right" /> </template>
              </a-button>
            </a-tooltip>
          </a-space>
        </div>
      </div>
      <div class="right">
        <div :style="previewShowStyle" class="show-preview">
          <img :src="newOptions.img" :style="previewStyle" alt="" />
        </div>
        <a-button
          :loading="newOptions.loading"
          class="cropper-submit"
          type="primary"
          @click="cropperSubmit"
          >提交</a-button
        >
      </div>
    </div>
  </a-modal>
</template>

<style>
* {
  margin: 0;
  padding: 0;
}
.cropper {
  display: flex;
  padding: 20px 0;
  .left {
    .cut {
      overflow: hidden;
    }
    .cropper-handle {
      margin-top: 20px;
    }
  }
  .right {
    position: relative;
    flex: 1;
    .show-preview {
      position: relative;
      top: 50%;
      left: 50%;
      overflow: hidden;
      transform: translate(-50%, -60%);
    }
    .cropper-submit {
      position: absolute;
      bottom: 0;
      left: 50%;
      transform: translate(-50%, 0);
    }
  }
}
</style>
